<template>
  <div class="layout_two" id="threeContain"></div>
</template>

<script lang="ts">
import { defineComponent, onMounted, onUnmounted, reactive, toRefs } from "vue";
import * as THREE from "three";
import Stats from "three/examples/jsm/libs/stats.module"; // 显示帧率
import { GUI } from "three/examples/jsm/libs/lil-gui.moldule.min.js"; // 引入GUI
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

let scene: any; // 场景
let mesh: any; // 网格模型

export default defineComponent({
  name: "Three",
  setup() {
    const state = reactive({
      camera: null as any, // 相机
      renderer: null as any, // 渲染器
      controls: null as any, // 控制
      stats: null as any,
      animateId: 0 as number,
    });

    /**
     * 初始化场景对象 Scene
     */
    const initScene = () => {
      scene = new THREE.Scene();

      const axesHelper = new THREE.AxesHelper(700);
      scene.add(axesHelper);
    };

    // 初始化网格模型 Mesh
    const initMesh = () => {
      const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
      const material = new THREE.MeshNormalMaterial();
      mesh = new THREE.Mesh(geometry, material);
    };

    // 初始化相机
    const initCamera = () => {
      //   const container = state.threeRef;
      const container = document.getElementById("threeContain") as HTMLElement;
      state.camera = new THREE.PerspectiveCamera(
        70,
        container.clientWidth / container.clientHeight,
        0.01,
        10
      );
      state.camera.position.z = 1;
    };

    // 初始化渲染器 Renderer
    const initRenderer = () => {
      const container = document.getElementById("threeContain") as HTMLElement;
      state.renderer = new THREE.WebGLRenderer({ antialias: true });
      state.renderer.setSize(container.clientWidth, container.clientHeight);
      container.appendChild(state.renderer.domElement);
    };

    // 初始化控件 Controls
    const initControls = () => {
      state.controls = new OrbitControls(
        state.camera,
        state.renderer.domElement
      );
    };

    // 初始化 Stats
    const initStats = () => {
      state.stats = new Stats();
      state.stats.domElement.style.position = "absolute";
      state.stats.domElement.style.left = "calc(100vw - 380px)";
      state.stats.domElement.style.top = "0px";
      const container = document.getElementById("threeContain") as HTMLElement;
      container.appendChild(state.stats.domElement);
    };

    // 初始化动画
    const animate = () => {
      state.animateId = requestAnimationFrame(animate);
      mesh.rotation.x += 0.01;
      mesh.rotation.y += 0.02;
      state.renderer.render(scene, state.camera);
      state.stats.update();
    };

    onMounted(() => {
      initScene(); // 初始化场景
      initMesh(); // 初始化网格模型
      scene.add(mesh); // 将网格模型添加到场景
      initCamera(); // 初始化相机
      initRenderer(); // 初始化渲染器
      initControls(); // 初始化控件
      initStats(); // 初始化Stats
      animate();
    });

    onUnmounted(() => {
      cancelAnimationFrame(state.animateId);
    });

    return {
      ...toRefs(state),
    };
  },
});
</script>

<style lang="scss" scoped>
</style>